package myJs.myPkg

import org.scalajs.dom.{BodyInit, Headers, HttpMethod, RequestInit, Response, fetch}

import scala.scalajs.js
import scala.scalajs.js.JSConverters._
import scala.scalajs.js.|
import scala.concurrent.ExecutionContext.Implicits.global

/**
 * Created by yz on 25/1/2022
 */
object MyFetch {

  def delete(url: String, headers: Map[String, String] = Map.empty, data: BodyInit = null,
             rsF: Response => js.Promise[js.Any] = rs => rs.json()) = {
    execDelete(url, headers, data, rsF)
  }

  def execDelete[T](url: String, headersMap: Map[String, String] = Map.empty, data: BodyInit = null,
                    rsF: Response => js.Promise[js.Any] = rs => rs.json()) = {
    fetch(url, init = new RequestInit {
      headers = headers2Headers(headersMap)
      method = HttpMethod.DELETE
      body = data
    }).toFuture.flatMap { response =>
      rsF(response).toFuture
    }
  }

  def post(url: String, headers: Map[String, String] = Map.empty, data: BodyInit = null,
           rsF: Response => js.Promise[js.Any] = rs => rs.json()) = {
    execPost(url, headers, data, rsF)
  }

  def postRnText(url: String, headers: Map[String, String] = Map.empty, data: BodyInit = null) = {
    myFetch(url, headers, data).flatMap { response =>
      response.text().toFuture
    }
  }

  def myFetch(url: String, headersMap: Map[String, String] = Map.empty, data: BodyInit = null) = {
    fetch(url, init = new RequestInit {
      headers = headers2Headers(headersMap)
      method = HttpMethod.POST
      body = data
    }).toFuture
  }

  def execPost[T](url: String, headersMap: Map[String, String] = Map.empty, data: BodyInit = null,
                  rsF: Response => js.Promise[js.Any] = rs => rs.json()) = {
    fetch(url, init = new RequestInit {
      headers = headers2Headers(headersMap)
      method = HttpMethod.POST
      body = data
    }).toFuture.flatMap { response =>
      rsF(response).toFuture
    }
  }

  def get(url: String, headers: Map[String, String] = Map.empty) = {
    execGet(url, headers)
  }

  def getRnStr(url: String, headers: Map[String, String] = Map.empty) = {
    myFetchGet(url, headers).flatMap { response =>
      response.text().toFuture
    }
  }

  def myFetchGet(url: String, headersMap: Map[String, String] = Map.empty) = {
    fetch(url, init = new RequestInit {
      headers = headers2Headers(headersMap)
    }).toFuture
  }

  def execGet(url: String, headersMap: Map[String, String] = Map.empty) = {
    fetch(url, init = new RequestInit {
      headers = headers2Headers(headersMap)
    }).toFuture.flatMap { response =>
      response.json().toFuture
    }
  }

  def headers2Headers(headers: Map[String, String] = Map.empty) = {
    val arrays = headers.toJSArray.map { case (k, v) =>
      js.Array(k, v)
    }
    new Headers(arrays)
  }


}
